<template>
  <div
    :id="`text-${textData.i}`"
    class="tinymce-body"
    :class="{
      'resize-tag': !readOnly,
      'edit-bg': KGraphStore.knowledgeGraphMode === 'edit',
    }"
    :style="containerStyle"
    @click.stop="handleClick"
  >
    <div v-if="!readOnly" class="drag-marker">
      <a-tooltip placement="top" title="点击删除">
        <div class="grid-item-close" @click.stop="deleteChart">
          <a-icon-font type="iconicon-beifen5" />
        </div>
      </a-tooltip>
    </div>
    <editor
      v-model="value"
      :disabled="readOnly"
      class="editor-box"
      api-key="no-api-key"
      :init="{
        menubar: false,
        inline: true,
        plugins: [
          'advlist autolink lists image charmap print preview anchor',
          'searchreplace visualblocks code fullscreen noneditable',
          'insertdatetime media table paste code help wordcount',
        ],
        noneditable_noneditable_class: 'mceNonEditable',
        toolbar_location: 'top',
        fixed_toolbar_container: `text-${textData.i}`,
        toolbar_sticky: true,
        toolbar: [
          {
            name: 'formatting',
            items: ['bold', 'italic', 'underline'],
          },
          {
            name: 'styles',
            items: ['fontselect', 'fontsizeselect'],
          },
          {
            name: 'color',
            items: ['forecolor', 'backcolor'],
          },
          {
            name: 'alignment',
            items: ['alignleft', 'aligncenter', 'alignright', 'alignjustify'],
          },
          {
            name: 'indentation',
            items: ['bullist', 'numlist', 'outdent', 'indent'],
          },
          {
            name: 'history',
            items: ['undo', 'redo'],
          },
        ],
        font_formats:
          'Andale Mono=andale mono,times; Arial=arial,helvetica,sans-serif; Book Antiqua=book antiqua,palatino; Comic Sans MS=comic sans ms,sans-serif; Courier New=courier new,courier; Helvetica=helvetica; Impact=impact,chicago; Tahoma=tahoma,arial,helvetica,sans-serif; Terminal=terminal,monaco; Times New Roman=times new roman,times; Trebuchet MS=trebuchet ms,geneva; Verdana=verdana,geneva; Wingdings=wingdings,zapf dingbats',
      }"
      @onBlur="handleBlur"
      @onChange="handleTextChange"
    />
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator'
import { Editor } from '@/components/common/tinymce/tinymce-editor'
import { cloneDeep, debounce } from 'lodash'
import Draggabilly from 'draggabilly'
import elementResizeDetectorMaker from 'element-resize-detector'
import KGraphStore from '@/store/modules/k-graph'

@Component({
  components: {
    Editor,
  },
})
export default class CommonTextEditor extends Vue {
  //  used in preivew/publish mode
  @Prop({
    type: Boolean,
    default() {
      return false
    },
  })
  readOnly?: boolean

  @Prop({
    default() {
      return {}
    },
  })
  textItem: any

  // 目前问题，多个文本组件，均显示在第一个box 中
  private value: any = ''
  public textData: any = {}
  public drag: any = null
  public panelWidth: number | null = null
  public panelHeight: number | null = null
  public panelTop: number | null = null
  public panelRight: number | null = null
  private firstRender: boolean = true

  public get KGraphStore() {
    return KGraphStore
  }

  public get containerStyle() {
    const {
      width = '300px',
      height = '100%',
      top = '0',
      right = '100px',
    } = this.textItem

    return {
      width,
      height,
      right,
      top,
    }
  }

  public initDragElement() {
    if (this.readOnly) {
      return
    }
    const that = this
    setTimeout(() => {
      const $overlay = document.querySelector(
        '.gis-map-component'
      ) as HTMLDivElement
      const $element = document.querySelector(
        `#text-${this.textItem.i}`
      ) as HTMLDivElement
      that.drag = new Draggabilly($element, {
        containment: $overlay,
        handle: `#text-${this.textItem.i} .drag-marker`,
        grid: [1, 1],
      })

      that.drag.on(
        'dragEnd',
        debounce(() => {
          const parent = document.querySelector(
            '.gis-map-component'
          ) as HTMLElement
          const result =
            parent?.clientWidth - that.drag.position.x - $element.clientWidth
          console.log(that.drag.position, 'result', result)

          that.panelRight = result
          that.panelTop = that.drag.position.y
          this.$emit('update-position', {
            top: `${that.panelTop}px`,
            right: `${that.panelRight}px`,
          })
        }, 300)
      )
    }, 500)
  }

  public initResize() {
    if (this.readOnly) {
      return
    }
    this.$nextTick(() => {
      const that = this
      const erdTable = elementResizeDetectorMaker()
      const auditTable = document.querySelector(
        `#text-${this.textItem.i}`
      ) as HTMLDivElement
      erdTable.listenTo(auditTable, (element: HTMLElement) => {
        that.changePanelsize(element.clientHeight, element.clientWidth)
      })
      this.$once('hook:beforeDestroy', () => {
        erdTable.removeAllListeners(auditTable)
      })
    })
  }

  public mounted() {
    this.initDragElement()
    this.initResize()
  }

  public deleteChart() {
    this.$emit('delete-text')
  }

  public changePanelsize = debounce((height: number, width: number) => {
    this._changePanelsize(height, width)
  }, 500)

  public _changePanelsize(height: number, width: number) {
    this.panelWidth = width
    this.panelHeight = height
    this.$emit('update-size', {
      width: `${width}px`,
      height: `${height}px`,
    })
  }

  @Watch('textItem', { immediate: true, deep: true })
  private handleTextItem(newValue: any) {
    if (newValue) {
      this.value = newValue.chartOptions.value
      this.textData = cloneDeep(newValue)
      if (this.firstRender) {
        this.initDragElement()
        this.initResize()
        this.firstRender = false
      }
    }
  }

  public handleClick() {
    const target = document.querySelector(
      `#text-${this.textData.i}`
    ) as HTMLElement
    if (!target.classList.contains('edit-bg')) {
      target.classList.add('edit-bg')
    }
  }

  public handleBlur() {
    const target = document.querySelector(
      `#text-${this.textData.i}`
    ) as HTMLElement
    if (target.classList.contains('edit-bg')) {
      target.classList.remove('edit-bg')
    }
    this.$emit('editor-blur')
  }

  public handleTextChange() {
    this.$emit('text-change', this.value)
  }
}
</script>

<style lang="less" scoped>
.resize-tag {
  &:hover {
    overflow: hidden;
    resize: both;
  }
}

.tinymce-body.edit-bg {
  background-color: rgba(255, 255, 255, 0.85);
}

.tinymce-body {
  background-color: rgba(255, 255, 255, 0);
  border-radius: 2px;
  display: flex;
  flex-direction: column;
  height: 300px;
  padding: 8px;
  position: absolute;
  top: 1px;
  width: 300px;

  &:hover {
    .grid-item-close {
      opacity: 1;
    }
  }
}

.drag-marker {
  cursor: grab;
  height: 20px;
  width: 100%;

  .grid-item-close {
    cursor: pointer;
    float: right;
    opacity: 0;
  }
}

.editor-box {
  height: calc(100% - 20px);
  outline: none;
  overflow-y: scroll;
  width: 100%;

  &::-webkit-scrollbar {
    width: 6px;
  }

  &:hover {
    &::-webkit-scrollbar-thumb {
      background: rgba(144, 147, 153, 0.5);
      border-radius: 6px;
    }

    &::-webkit-scrollbar-track {
      background: transparent;
      border-radius: 5px;
    }
  }
}

.remove-scroll {
  overflow: hidden;
}
</style>
